package com.fcg.redis.topone.service.impl;

import com.fcg.redis.rediscommon.util.KeyUtils;
import com.fcg.redis.topone.bean.*;
import com.fcg.redis.topone.service.ReadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author FCG
 */
@Slf4j
@Service
public class ReadServiceImpl implements ReadService {

    private static final String NAME_SPACE = "MSG_READ";

    private static List<User> userList = new ArrayList<>();
    private static List<Goods> goodsList = new ArrayList<>();
    private static List<News> newsList = new ArrayList<>();
    private static List<Video> videoList = new ArrayList<>();

    @Resource(name = "redisTemplate")
    private ZSetOperations zSetOperations;

    static {
        userList.add(User.builder().id("u01").name("Tom").build());
        userList.add(User.builder().id("u02").name("Jerry").build());
        userList.add(User.builder().id("u03").name("张三").build());
        userList.add(User.builder().id("u04").name("李四").build());

        goodsList.add(Goods.builder().id("b01").name("Apple iPhone 11").build());
        goodsList.add(Goods.builder().id("b02").name("HUAWEI Mate 30 Pro").build());
        goodsList.add(Goods.builder().id("b03").name("荣耀20S").build());
        goodsList.add(Goods.builder().id("b04").name("一加 OnePlus 7 Pro").build());

        newsList.add(News.builder().id("n01").content("弗朗西斯出售豪宅").build());
        newsList.add(News.builder().id("n02").content("中国亚美尼亚免签").build());
        newsList.add(News.builder().id("n03").content("新疆阿克苏地震").build());
        newsList.add(News.builder().id("n04").content("福斯影业改名字").build());

        videoList.add(Video.builder().id("v01").url("http://video.com/play").build());
        videoList.add(Video.builder().id("v02").url("http://video.com/play").build());
        videoList.add(Video.builder().id("v03").url("http://video.com/play").build());
        videoList.add(Video.builder().id("v04").url("http://video.com/play").build());

    }

    /**
     * 读取消息
     *
     * @param msgType msgType
     * @param userId  userId
     * @param msgId   msgId
     */
    @SuppressWarnings("unchecked")
    @Override
    public void read(MsgType msgType, String userId, String msgId) {
        long timestamp = System.currentTimeMillis();
        String key = getRedisKey(msgType, userId);
        zSetOperations.add(key, msgId, timestamp);
        log.info("read msg, add key:{}", key);
    }

    /**
     * 是否已读
     *
     * @param msgType msgType
     * @param userId  userId
     * @param msgId   msgId
     * @return isRead
     */
    @SuppressWarnings("unchecked")
    @Override
    public boolean isRead(MsgType msgType, String userId, String msgId) {
        String key = getRedisKey(msgType, userId);
        log.info("check isRead, key:{}", key);
        Double timestamp = zSetOperations.score(key, msgId);
        if (Objects.isNull(timestamp)) {
            //该消息id不存在，未读
            return false;
        }
        long now = System.currentTimeMillis();
        if (now - timestamp > msgType.getTtl()) {
            //数据已经失效
            evictExpireData(msgType, userId, msgId);
            return false;
        }
        return true;
    }

    /**
     * 清除过期的数据
     */
    @SuppressWarnings("unchecked")
    private void evictExpireData(MsgType msgType, String userId, String msgId) {
        String key = getRedisKey(msgType, userId);
        long now = System.currentTimeMillis();
        log.info("remove data, from {}, to {}", 0, now - msgType.getTtl());
        zSetOperations.removeRangeByScore(key, 0, now - msgType.getTtl());
    }

    private String getRedisKey(MsgType msgType, String userId) {
        return KeyUtils.concat(":", NAME_SPACE, msgType.ordinal(), userId);
    }
}
